﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Threading;

namespace Update.Utility
{
	public class FtpDownloader
	{
		private FtpWebRequest reqFTP;
		private int downloadedSize;
		private int totalSize;

		#region DownloadEvent
		public class DownloadEventArgs : EventArgs
		{
			public readonly int FinishedPercent;
			public readonly String Type;
			public DownloadEventArgs(int finishedPercent, String type)
			{
				FinishedPercent = finishedPercent;
				Type = type;
			}
		}
		//委托
		public delegate void DownloadEventHandler(Object sender, DownloadEventArgs e);

		//事件
		public event DownloadEventHandler DownloadEvent;

		private void RaiseDownloadEvent(int count)
		{
			downloadedSize += count;
			DownloadEvent(this, new DownloadEventArgs((int)(((float)downloadedSize / totalSize) * 100), ""));
		}
		#endregion


		private bool Connect(String url)
		{
			try
			{
				reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(url));
				reqFTP.UseBinary = true;
				return true;
			}
			catch
			{
				return false;
			}
		}


		private String[] GetFileList(String path)
		{
			StringBuilder result = new StringBuilder();

			try
			{
				if (!Connect(path))
				{
					return null;
				}

				reqFTP.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
				WebResponse response = reqFTP.GetResponse();

				// 设置语言
				StreamReader reader = new StreamReader(response.GetResponseStream(),
					System.Text.Encoding.Default);

				String line = reader.ReadLine();
				while (line != null)
				{
					result.Append(line);
					result.Append("\n");
					line = reader.ReadLine();
				}

				result.Remove(result.ToString().LastIndexOf('\n'), 1);
				reader.Close();
				response.Close();

				return result.ToString().Split('\n');
			}
			catch
			{
				return null;
			}
		}


		public void Download(String url, String fileName)
		{
			String[] files = GetFileList(url);
			if (files == null)
			{
				return;
			}

			try
			{
				String[] temp = files[0].Trim().Split(new String[] { " " }, StringSplitOptions.RemoveEmptyEntries);
				totalSize = Convert.ToInt32(temp[2].Trim());
			}
			catch
			{
				return;
			}
			DownloadSingleFile(url, fileName);
		}

	
		private bool DownloadSingleFile(String url, String fileName)
		{
			try
			{
				Connect(url);

				reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;

				WebResponse response = reqFTP.GetResponse();
				Stream ftpStream = response.GetResponseStream();
				long cl = response.ContentLength;
				int bufferSize = 2048;
				int readCount;
				byte[] buffer = new byte[bufferSize];
				readCount = ftpStream.Read(buffer, 0, bufferSize);
				FileStream outputStream = new FileStream(fileName, FileMode.Create);
				while (readCount > 0)
				{
					outputStream.Write(buffer, 0, readCount);
					outputStream.Flush();
					RaiseDownloadEvent(readCount);
					readCount = ftpStream.Read(buffer, 0, bufferSize);
				}

				ftpStream.Close();
				outputStream.Close();
				response.Close();

				return true;
			}
			catch
			{
				return false;
			}
		}
	}
}